#include <windows.h>
#include <stdio.h>
#include "include/pointers.h"

#define SPEEDHACK_PRIV	PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION

void set_speed(HANDLE rom_process, float speed)
{
    unsigned int    base;
    unsigned int    player;
    
    /* Read Base Pointer */
    if(ReadProcessMemory(rom_process, BASE_PTR, &base, 4, 0) == 0)
    {
        fprintf(stderr, "set_speed: could not read base pointer: error number %lu\n", GetLastError());
        return;
    }
    
    /* Read Player Pointer */
    if(ReadProcessMemory(rom_process, (void *)(base + 0x598), &player, 4, 0) == 0)
    {
        fprintf(stderr, "set_speed: could not read player pointer: error number %lu\n", GetLastError());
        return;
    }
    
    /* write Run Speed */
    if(WriteProcessMemory(rom_process, (void *)(player + 0x040), &speed, 4, NULL) == 0)
    {           
        fprintf(stderr, "set_speed: could not write runspeed: error number %lu\n", GetLastError());
        return;
    }
    printf("Speed set to %.1f\n", speed);
}

float get_speed(HANDLE rom_process)
{
    unsigned int    base;
    unsigned int    player;
    float           speed;
    
    /* Read Base Pointer */
    if(ReadProcessMemory(rom_process, BASE_PTR, &base, 4, 0) == 0)
    {
        fprintf(stderr, "get_speed: Could not read base pointer: error number %lu\n", GetLastError());
        return 0.0;
    }
    
    /* Read Player Pointer */
    if(ReadProcessMemory(rom_process, (void *)(base + 0x598), &player, 4, 0) == 0)
    {
        fprintf(stderr, "get_speed: Could not read player pointer: error number %lu\n", GetLastError());
        return 0.0;
    }
    
    /* Read Run Speed */
    if(ReadProcessMemory(rom_process, (void *)(player + 0x040), &speed, 4, 0) == 0)
    {           
        fprintf(stderr, "get_speed: Could not read runspeed: error number %lu\n", GetLastError());
        return 0.0;
    }

    return speed;
}


int main(int argc, char **argv)
{
    HANDLE          rom_process;
    int             rom_pid;
    float           runspeed;
    
    /* get pid */
    if(argc < 2)
    {
        printf("If you don't know what this is or where to find it read the readme file.\nEnter the RoM process ID: ");
        scanf("%d", &rom_pid);
    }
    else
    {
        sscanf(argv[1], "%d", &rom_pid);
    }
    /* open process for reading */
    rom_process = OpenProcess(SPEEDHACK_PRIV, 0, rom_pid);
    if(rom_process == NULL)
    {
        puts("Failed to open process :(");
        return 1;
    }
    
    /* Loop for hotkeys*/
    while(1)
    {
        if(GetAsyncKeyState(VK_F8) & 0x00FF)
        {
            set_speed(rom_process, 50.0);
        }
        if(GetAsyncKeyState(VK_F7) & 0x00FF)
        {
            runspeed = get_speed(rom_process);
            if(runspeed != 0.0)
                set_speed(rom_process, runspeed + 5.0);
        }
        if(GetAsyncKeyState(VK_F6) & 0x00FF)
        {
            runspeed = get_speed(rom_process);
            if(runspeed != 0.0)
                set_speed(rom_process, runspeed - 5.0);
        }
        Sleep(100);
    }
}
